<?php
/**
 * Copyright 2011  SURFfoundation
 * 
 * This file is part of ESCAPE.
 * 
 * ESCAPE is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * ESCAPE is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with ESCAPE.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * For more information:
 * http://escapesurf.wordpress.com/
 * http://www.surffoundation.nl/
 * 
 * Contact: d.vierkant@utwente.nl
 * 
 * @license http://www.gnu.org/licenses/gpl.html GNU GPLv3
 */
?>
<?php
/**
 * HTTP utils
 * 
 * Provides some basic HTTP methods.
 */
class httputils_HttpUtils
{
	/**
	  * Improves memory consumptions and works around buggy readfile() in PHP 5.0.4 (2MB readfile limit).
	  */
	public static function readFileChunked($filename, $retbytes = true, $optional_headers = null, $username = null, $password = null)
	{
		if($username !== null)
		{
			if($optional_headers === null)
			{
				$optional_headers = '';
			}
			$optional_headers = "Authorization: Basic " . base64_encode($username . ':' . $password) . "\r\n" . $optional_headers;
		}
		
		if($optional_headers !== null)
		{
			$params['http']['header'] = $optional_headers;
		}
		
		$ctx = stream_context_create($params);
		
		$chunksize = 1*(1024*1024); // 1MB chunks - must be less than 2MB!
		$buffer = '';
		$cnt =0;
		$handle = fopen($filename, 'rb', false, $ctx);
		if($handle === false)
		{
			return false;
		}
	
		while(!feof($handle))
		{
			@set_time_limit(60*60); //reset time limit to 60 min - should be enough for 1 MB chunk
			$buffer = fread($handle, $chunksize);
			echo $buffer;
			flush();
			if ($retbytes)
			{
			   $cnt += strlen($buffer);
			}
		}
		$status = fclose($handle);
		if($retbytes && $status)
		{
			return $cnt; // return num. bytes delivered like readfile() does.
		}
		return $status;
	}
	
	
	public static function copyFileChunked($filename, $destinationResource, $optional_headers = null, $username = null, $password = null)
	{
		if($username !== null)
		{
			if($optional_headers === null)
			{
				$optional_headers = '';
			}
			$optional_headers = "Authorization: Basic " . base64_encode($username . ':' . $password) . "\r\n" . $optional_headers;
		}
		
		if($optional_headers !== null)
		{
			$params['http']['header'] = $optional_headers;
		}
		
		$ctx = stream_context_create($params);
		
		$chunksize = 1*(1024*1024); // 1MB chunks - must be less than 2MB!
		$buffer = '';
		$cnt =0;
		$handle = fopen($filename, 'rb', false, $ctx);
		if($handle === false)
		{
			return false;
		}
	
		while(!feof($handle))
		{
			@set_time_limit(60*60); //reset time limit to 60 min - should be enough for 1 MB chunk
			$buffer = fread($handle, $chunksize);
			fwrite($destinationResource, $buffer);
			if ($retbytes)
			{
			   $cnt += strlen($buffer);
			}
		}
		$status = fclose($handle);
		if($retbytes && $status)
		{
			return $cnt; // return num. bytes delivered like readfile() does.
		}
		return $status;
	}
	
	/**
	 * Do a HTTP POST request and return the result as a string.
	 * @param string $url URL
	 * @param string $data POST data, create using: http_build_query()
	 * @param array $optional_headers Optional headers
	 * @return string Response string
	 */
	public static function doPostRequest($url, $data, $optional_headers = null, $username = null, $password = null)
	{
		$params = array('http' => array(
									'method' => 'POST',
									'content' => $data
						));
		
		if($username !== null)
		{
			if($optional_headers === null)
			{
				$optional_headers = '';
			}
			$optional_headers = "Authorization: Basic " . base64_encode($username . ':' . $password) . "\r\n" . $optional_headers;
		}
		
		if($optional_headers !== null)
		{
			$params['http']['header'] = $optional_headers;
		}
		
		$ctx = stream_context_create($params);
		
		$handle = @fopen($url, 'rb', false, $ctx);
		if(!$handle)
		{
			throw new Exception("Problem with $url");
		}
		
		$response = @stream_get_contents($handle);
		if ($response === false)
		{
			throw new Exception("Problem reading data from " . $url);
		}
		
		fclose($handle);
		
		return $response;
	}
	
	/**
	 * Do a HTTP POST request and return the result as a file pointer.
	 * @param string $url URL
	 * @param string $data POST data, create using: http_build_query()
	 * @param array $optional_headers Optional headers
	 * @return string Response file pointer
	 */
	public static function doPostRequestFilePointer($url, $data, $optional_headers = null, $username = null, $password = null)
	{
		$params = array('http' => array(
									'method' => 'POST',
									'content' => $data
						));
		
		if($username !== null)
		{
			if($optional_headers === null)
			{
				$optional_headers = '';
			}
			$optional_headers = "Authorization: Basic " . base64_encode($username . ':' . $password) . "\r\n" . $optional_headers;
		}
		
		if($optional_headers !== null)
		{
			$params['http']['header'] = $optional_headers;
		}
		
		$ctx = stream_context_create($params);
		
		$handle = @fopen($url, 'rb', false, $ctx);
		if(!$handle)
		{
			throw new Exception("Problem with " . $url);
		}
		
		return $handle;
	}
	
}